Parameter guide¶
What is a parameter?¶
A parameter usually represents a single value of a single feature of an instrument, e.g. the frequency of a function generator, the mode of a multimeter (resistance, current, or voltage), or the input impedance of an oscilloscope channel. Basic attributes of a Parameter
are:
name
: the name used internally by QCoDeS, e.g. ‘input_impedance’label
: the label to use for plotting this parameterunit
: the physical unit. ALWAYS use SI units if a unit is applicableset_cmd
, the command to set the parameter. Either a SCPI string with a single ‘{}’, or a function taking one argument (see examples below)get_cmd
: the command to get the parameter. Follows the same scheme asset_cmd
Note that there are many more attributes, the full list can be found in the Parameter documentation.
microwave_source.frequency
, in which case microwave_source
is an Instrument
, and the Parameter is frequency
.microwave_source.frequency(42e9) # Set microwave source frequency to 42 GHz
microwave_source.frequency() # Get frequency
>>> 42e9
Note that these set/get commands do not simply set a variable in Python; usually they actually send VISA commands to the instrument to get/set the frequency. For examples, look at the QCoDeS drivers.
Note: The new QCoDeS DataSet has dropped the requirement of only sweeping and measuring Parameters (more specifically it does not rely on the Loop
class). However, our group’s version of QCoDeS has not switched to this method.
Parameter types¶
DataArray
can be determined during a measurement. - MultiParameter The MultiParameter can hold multiple values. Each of these values can be either a single value (like a Parameter
), or an array (like an ArrayParameter
).Parameter
.ArrayParameter
and MultiParameter
see the docs/examples/Parameters.ipynb
notebookInstrument-independent parameters¶
[ ]:
from qcodes import Parameter
param = Parameter('param', set_cmd=None) # Default set_cmd is False, in which case we cannot set it (see below)
param(42) # set value
param() # get value
42
get
/set
.get_cmd
and set_cmd
passed during instantiation:get_cmd: Function to call during get command. Must accept zero arguments, and return value. If attached to an Instrument, it can also be a string, which corresponds to the VISA command. Can also be
False: Raise an error when a get is called
None: Return latest set value (This is the default)
set_cmd: Function to call during set command Must accept one argument, which is the value being set If attached to an Instrument, it can also be a string, which corresponds to the VISA command. Can also be False and None (see above), the default being False.
As an example, here we create a parameter with a specific action during get and set: - During a get
, it will return a random value between 0 and 1 - During a set
, it will print the value it’s being set to.
[ ]:
import numpy as np
def print_value(value):
print('Value set to', value)
p = Parameter('param', get_cmd=np.random.uniform, set_cmd=print_value)
p(42) # Setting calls a print statement
p() # Get return a random value between 0 and 1
Value set to 42
0.960839463495372
Parameter
and _BaseParameter
.Subclassing parameters¶
While the get_cmd
/set_cmd
are sufficient for most needs, more complex situations can arise where simple commands do not suffice. For example, the parameter is not passed as self
, and so the get/set function cannot access other parameter attributes. In these cases, it is better to subclass the Parameter and add these functionalities in the subclass.
To demonstrate this, we create a parameter that either returns the latest set value, or the exponent of that value depending on the boolean attribute exponentiate
:
[ ]:
class ExponentiateParameter(Parameter):
exponentiate = False
def get_raw(self):
if self.exponentiate:
return np.exp(self.raw_value)
else:
return self.raw_value
[ ]:
exponentiate_parameter = ExponentiateParameter('exponentiation', initial_value=3)
print('Without exponentiation:', exponentiate_parameter())
exponentiate_parameter.exponentiate = True
print('With exponentiation:', exponentiate_parameter())
Without exponentiation: 3
With exponentiation: 20.085536923187668
Subclassing Parameters can be a very useful way to create complex parameters with many functions (e.g. a retuning sequence).
Note: A third way to add get/set commands is through the ParameterNode (see below)
Parameter set callbacks¶
measure_temperature
to the magnetic field parameter (via magnetic_field.connect
)[ ]:
def measure_temperature(value):
print(f'Temperature is at {np.random.randint(0, 300)} K')
magnetic_field = Parameter('magnetic_field', set_cmd=None)
magnetic_field.connect(measure_temperature,
update=True) # Update value to perform initial temperature_measurement
print('Setting magnetic field to 1T')
magnetic_field(1)
print('Setting magnetic field to 2T')
magnetic_field(2)
Temperature is at 53 K
Setting magnetic field to 1T
Temperature is at 241 K
Setting magnetic field to 2T
Temperature is at 54 K
param2
to param1
with an offset of 2:[ ]:
param1 = Parameter('param1', set_cmd=None)
param2 = Parameter('param2', set_cmd=None)
param1.connect(param2, offset=2, update=False)
param1(42)
param2()
44
Linking a parameter to config¶
Note: This feature is only available with SilQ, which uses the SubConfig
.
[ ]:
from silq import config
config.properties.read_duration = 1
config
{'properties': {'read_duration': 1}}
[ ]:
read_duration = Parameter('read_duration', set_cmd=None, initial_value=0)
read_duration()
0
properties.read_duration
.[ ]:
read_duration.set_config_link('config:properties.read_duration') # Note that config paths start with `config:`
read_duration()
0
However, once we modify the value in the config, the parameter value does change:
[ ]:
config.properties.read_duration = 2
read_duration()
2